﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Package;
using VsCommands = Microsoft.VisualStudio.VSConstants.VSStd97CmdID;
using VsCommands2K = Microsoft.VisualStudio.VSConstants.VSStd2KCmdID;
using EnvDTE;
using VSLangProj;

namespace Microsoft.StoryboardDesigner.Platform.CustomProjects
{
    [Guid("94E8F2D8-BA2B-4847-BECC-CB9710758AC8")]
    public class StoryboardDesignerProjectNode : ProjectNode
    {
        #region Constants
        internal const string ProjectTypeName = "StoryboardDesigner";
        #endregion

        #region Fields
        private VsPackage package;
        internal static int imageOffset;
        private static ImageList imageList;
        private static Guid guid1;
        private VSLangProj.VSProject vsProject;
        #endregion

        #region Constructors
        static StoryboardDesignerProjectNode()
        {
            imageList = Utilities.GetImageList(typeof(StoryboardDesignerProjectNode).Assembly.GetManifestResourceStream("Microsoft.StoryboardDesigner.Platform.Resources.StoryboardProjectImageList.bmp"));
            guid1 = new Guid("79989DD6-4C13-4D10-9872-73538668D037");
        }

        public StoryboardDesignerProjectNode(VsPackage package)
        {
            this.package = package;

            InitializeImageList();
            InitializeCATIDs();
        }
        #endregion

        #region Properties
        public static ImageList ImageList
        {
            get
            {
                return imageList;
            }
            set
            {
                imageList = value;
            }
        }

        protected internal VSLangProj.VSProject VSProject
        {
            get
            {
                if(vsProject == null)
                {
                    vsProject = new Microsoft.VisualStudio.Package.Automation.OAVSProject(this);
                }

                return vsProject;
            }
        }
        #endregion

        #region Overriden implementation
        public override Guid ProjectGuid
        {
            get { return typeof(StoryboardDesignerProjectFactory).GUID; }
        }

        public override string ProjectType
        {
            get { return ProjectTypeName; }
        }

        public override int ImageIndex
        {
            get
            {
                return imageOffset + (int)StoryboardProjectImageName.Project;
            }
        }

        protected override NodeProperties CreatePropertiesObject()
        {
            return new StoryboardDesignerProjectNodeProperties(this);
        }

        public override object GetAutomationObject()
        {
            return new OAStoryboardDesignerProject(this);
        }

        public override int ExecCommand(uint itemId, ref Guid guidCmdGroup, uint nCmdId, uint nCmdExecOpt, IntPtr pvain, IntPtr p)
        {
            if(guidCmdGroup == VsMenus.guidStandardCommandSet97)
            {
                switch((VsCommands)nCmdId)
                {
                    case VsCommands.CleanCtx:
                    case VsCommands.BuildCtx:
                    case VsCommands.RebuildCtx:
                    case VsCommands.BuildOrder:
                    case VsCommands.SetStartupProject:
                    case VsCommands.ProjectSettings:
                    case VsCommands.ProjectProperties:
                    case VsCommands.PropSheetOrProperties:
                    case VsCommands.ProjectDependencies:
                    case VsCommands.Properties:
                    case VsCommands.PropertyPages:
                    case VsCommands.DebugOptions:
                    case VsCommands.StartNoDebug:
                    //case VsCommands.UnloadProject:
                        return VSConstants.S_OK;
                }
            }
            else if(guidCmdGroup == VsMenus.guidStandardCommandSet2K)
            {
                switch((VsCommands2K)nCmdId)
                {
                    case VsCommands2K.DEPENDENCIES:
                    case VsCommands2K.PROJSETTINGS:
                    case VsCommands2K.ADDREFERENCE:
                    case VsCommands2K.PROJSTARTDEBUG:
                    case VsCommands2K.PROJSTEPINTO:
                    case VsCommands2K.Debug:
                        return VSConstants.S_OK;
                }
            }
            else if(guidCmdGroup == guid1)
            {
                switch(nCmdId)
                {
                    case 768: //Generate Code Metrics
                        return VSConstants.S_OK;
                }
            }

            return base.ExecCommand(itemId, ref guidCmdGroup, nCmdId, nCmdExecOpt, pvain, p);
        }

        protected override QueryStatusResult QueryStatusCommandFromOleCommandTarget(Guid cmdGroup, uint cmd, out bool handled)
        {
            if(cmdGroup == VsMenus.guidStandardCommandSet97)
            {
                switch((VsCommands)cmd)
                {
                    case VsCommands.ViewCode:
                    case VsCommands.CleanCtx:
                    case VsCommands.BuildCtx:
                    case VsCommands.RebuildCtx:
                    case VsCommands.BuildOrder:
                    case VsCommands.SetStartupProject:
                    case VsCommands.ProjectSettings:
                    case VsCommands.ProjectProperties:
                    case VsCommands.PropSheetOrProperties:
                    case VsCommands.ProjectDependencies:
                    case VsCommands.Properties:
                    case VsCommands.PropertyPages:
                    case VsCommands.DebugOptions:
                    case VsCommands.StartNoDebug:
                    //case VsCommands.UnloadProject:
                        handled = true;
                        return QueryStatusResult.NOTSUPPORTED | QueryStatusResult.INVISIBLE;
                }
            }
            else if(cmdGroup == VsMenus.guidStandardCommandSet2K)
            {
                switch((VsCommands2K)cmd)
                {
                    case VsCommands2K.DEPENDENCIES:
                    case VsCommands2K.PROJSETTINGS:
                    case VsCommands2K.ADDREFERENCE:
                    case VsCommands2K.PROJSTARTDEBUG:
                    case VsCommands2K.PROJSTEPINTO:
                    case VsCommands2K.Debug:
                        handled = true;
                        return QueryStatusResult.NOTSUPPORTED | QueryStatusResult.INVISIBLE;
                }
            }
            else if(cmdGroup == guid1)
            {
                switch(cmd)
                {
                    case 768: //Generate Code Metrics
                        handled = true;
                        return QueryStatusResult.NOTSUPPORTED | QueryStatusResult.INVISIBLE;
                }
            }

            return base.QueryStatusCommandFromOleCommandTarget(cmdGroup, cmd, out handled);
        }

        public override FileNode CreateFileNode(ProjectElement item)
        {
            StoryboardDesignerProjectFileNode node = new StoryboardDesignerProjectFileNode(this, item);
            
            node.OleServiceProvider.AddService(typeof(Project), new OleServiceProvider.ServiceCreatorCallback(this.CreateServices), false);
            node.OleServiceProvider.AddService(typeof(ProjectItem), node.ServiceCreator, false);
            node.OleServiceProvider.AddService(typeof(VSProject), new OleServiceProvider.ServiceCreatorCallback(this.CreateServices), false);

            return node;
        }

        protected override ReferenceContainerNode CreateReferenceContainerNode()
        {
            return null;
        }
        #endregion

        #region Private implementation
        private void InitializeImageList()
        {
            imageOffset = this.ImageHandler.ImageList.Images.Count;

            foreach(Image img in ImageList.Images)
            {
                this.ImageHandler.AddImage(img);
            }
        }

        private void InitializeCATIDs()
        {
            this.AddCATIDMapping(typeof(StoryboardDesignerProjectNodeProperties), typeof(StoryboardDesignerProjectNodeProperties).GUID);
            this.AddCATIDMapping(typeof(StoryboardDesignerProjectFileNodeProperties), typeof(StoryboardDesignerProjectFileNodeProperties).GUID);
        }

        private object CreateServices(Type serviceType)
        {
            object service = null;
            if(typeof(VSLangProj.VSProject) == serviceType)
            {
                service = this.VSProject;
            }
            else if(typeof(EnvDTE.Project) == serviceType)
            {
                service = this.GetAutomationObject();
            }
            return service;
        }
        #endregion
    }
}
